package org.dtrd.modules.record.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dtrd.base.BaseController;
import org.dtrd.common.api.vo.Result;
import org.dtrd.config.system.Constant;
import org.dtrd.config.system.SystemState;
import org.dtrd.modules.base.service.BaseCommonService;
import org.dtrd.modules.record.entity.bean.*;
import org.dtrd.modules.record.entity.request.SugarValueRequest;
import org.dtrd.modules.record.entity.request.TimePeriodRequest;
import org.dtrd.modules.record.service.IDtrdEntRdUplowRecordService;
import org.dtrd.modules.record.service.ISugarRecordService;
import org.dtrd.modules.util.SchemeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static org.dtrd.common.constant.CommonConstant.*;

/**
 * 血糖记录
 *
 * @author 萧
 * @date:2021--16 8:17 下午
 **/
@RestController
@RequestMapping("/101/01")
@Slf4j
@Api(tags = "血糖打卡记录")
public class SugarRecordController extends BaseController {

    @Autowired
    private ISugarRecordService sugarRecordService;
    @Autowired
    private IDtrdEntRdUplowRecordService uplowRecordService;
    @Autowired
    private BaseCommonService baseCommonService;

    @ApiOperation("添加或修改血糖")
    @PostMapping(value = "/1010104")
    public Result<?> add(@RequestBody SugarValueBean value) {
        // 添加校验: patientId timeType value 记录时间
        if (isIntParamInvalid(value.getPatientId())
                || isIntParamInvalid(value.getType())
                || value.getValue() == null
                || value.getTime() == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        boolean result = sugarRecordService.saveSugarRecord(value);
        String logContent = String.format("添加或修改血糖，患者id：%d, 记录时间类型: %d, 时间: %s", value.getPatientId(), value.getType(), value.getTime());
        baseCommonService.addLog(logContent, OPERATE_TYPE_SAVE_OR_UPDATE);
        return result ? Result.OK() : error(SystemState.ResponseState.STATE_OPERATION_FAILURE);
    }

    @ApiOperation("血糖曲线查询")
    @PostMapping("/1010101")
    public Result<?> getSugarListByTimePeriod(@RequestBody TimePeriodRequest request) {
        if (request.getPatientId() == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        String startDate = null;
        String endDate = null;
        String[] timePeriod = handleTimePeriod(request);
        if (timePeriod != null) {
            startDate = timePeriod[0];
            endDate = timePeriod[1];
        }
        if (startDate == null || endDate == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        int sourceType = request.getSourceType() == null ? 0 : request.getSourceType();
        int patientId = request.getPatientId();
        SugarChart sugarChart = sugarRecordService.getBloodSugarRecordsForCharts(patientId, startDate, endDate, sourceType);
        String logContent = String.format("血糖曲线查询，查询患者id：%d", request.getPatientId());
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(sugarChart);
    }

    @ApiOperation(value = "按日期分组获取患者血糖记录", notes = "每日每个时段类型取最近一条数据")
    @PostMapping("/1010102")
    public Result<?> getPatientSugarRecordDaily(@RequestBody TimePeriodRequest request) {
        if (request.getPatientId() == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        Integer page = getIntParam(request.getPage(), 1);
        Integer pageSize = getIntParam(request.getPageSize(), 20);
        String startDate = null;
        String endDate = null;
        String[] timePeriod = handleTimePeriod(request);
        if (timePeriod != null) {
            startDate = timePeriod[0];
            endDate = timePeriod[1];
        }
        if (startDate == null || endDate == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        Integer patientId = request.getPatientId();
        Integer sourceType = request.getSourceType() == null ? 0 : request.getSourceType();
        Integer count = sugarRecordService.getSugarRecordDateCount(patientId, startDate, endDate, sourceType);
        JSONObject obj = new JSONObject();
        if (count != null && count > 0) {
            List<DailySugarRecordBean> list;
            if (sourceType.equals(Constant.SugarSourceType.SOURCE_SGBL_BLE.getType())) {
                list = sugarRecordService.getSGBLSugarRecord(patientId, startDate, endDate, page, pageSize, sourceType);
            }else {
                list = sugarRecordService.getDailySugarRecord(patientId, startDate, endDate, page, pageSize);
//                SchemeUtil.checkSugarStatus(patientId, list);
            }
            obj.put("recordList", list);
            int totalPage;
            if (count <= pageSize || pageSize <= 0) {
                totalPage = 1;
            } else {
                totalPage = count / pageSize;
                if (count % pageSize != 0) {
                    totalPage += 1;
                }
            }
            obj.put("totalPage", totalPage);
            obj.put("count", count);
        } else {
            obj.put("recordList", Collections.EMPTY_LIST);
            obj.put("totalPage", 1);
            obj.put("count", 0);
        }
        String logContent = String.format("按日期分组获取患者血糖记录，查询患者id：%d", request.getPatientId());
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(obj);
    }

    @ApiOperation("查询血糖统计数据 按照血糖记录类别进行统计， 总次数，最高、最低值、平均值、偏高、偏低、正常次数")
    @PostMapping(value = "/1010103")
    public Result<?> getBloodSugarStatisticsByRecordType(@RequestBody TimePeriodRequest request) {
        Integer patientId = request.getPatientId();
        Integer type = request.getType();
        String startTime = request.getStartTime();
        String endTime = request.getEndTime();
        Integer period = request.getPeriod();

        try {
            if (patientId <= 0 || (type != 3 && StringUtils.isEmpty(startTime))) {
                return Result.error(SystemState.ResponseState.STATE_PARAMS_ERROR.getCode(), SystemState.ResponseState.STATE_PARAMS_ERROR.getMsg());
            } else {
                Map map = sugarRecordService.getBloodSugarStatisticsByRecordType(patientId, type, startTime, endTime, period);
                String logContent = String.format("查询血糖统计数据，查询患者id：%d", patientId);
                baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
                return Result.OK(map);
            }
        } catch (Exception e) {
            log.error("获取血糖统计信息异常", e);
            return Result.error(SystemState.ResponseState.STATE_OPERATION_FAILURE.getCode(), SystemState.ResponseState.STATE_OPERATION_FAILURE.getMsg());
        }
    }

    @ApiOperation("查询侧边栏血糖信息")
    @GetMapping("/1010105")
    public Result<?> getLastSugarRecord(@RequestParam Integer patientId) {
        if (isIntParamInvalid(patientId)) {
            return error(SystemState.ResponseState.STATE_PARAMS_ERROR);
        }
        // 最近一次的血糖记录, 假设查询的记录如果不为空则其每一项都是有值的
        SugarValueBean sugarValue = sugarRecordService.selectLastRecordByPatientId(patientId);
        ValueUplowBean sugarValueUpLowRecord = uplowRecordService.getSugarValueUpLowRecord(null, patientId);
        // 设置侧边栏血糖信息
        SidebarSugar sidebarSugar = new SidebarSugar();
        // 如果没有血糖记录则 value 和 date 都会返回 null
        if (sugarValue != null) {
            sidebarSugar.setValue(sugarValue.getValue());
            sidebarSugar.setDate(sugarValue.getTime());
        }
        // 餐前
        sidebarSugar.setPreLow(sugarValueUpLowRecord.getLowerValueBeforeMeal());
        sidebarSugar.setPreUp(sugarValueUpLowRecord.getUpperValueBeforeMeal());
        // 餐后
        sidebarSugar.setPropLow(sugarValueUpLowRecord.getLowerValueAfterMeal());
        sidebarSugar.setPropUp(sugarValueUpLowRecord.getUpperValueAfterMeal());
        // 睡前
        sidebarSugar.setBeforeSleepLow(sugarValueUpLowRecord.getLowerValueBeforeSleep());
        sidebarSugar.setBeforeSleepUp(sugarValueUpLowRecord.getUpperValueBeforeSleep());
        // 空腹
        sidebarSugar.setLimosisLow(sugarValueUpLowRecord.getLowerValueLimosis());
        sidebarSugar.setLimosisUp(sugarValueUpLowRecord.getUpperValueLimosis());
        String logContent = String.format("查询侧边栏血糖信息，查询患者id：%d", patientId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return Result.OK(sidebarSugar);
    }

    @ApiOperation("设置血糖上下限")
    @PostMapping("/1010106")
    public Result<?> saveSugarValueUplowRecord(@RequestBody ValueUplowBean sugarValueUplow){
        if (isIntParamInvalid(sugarValueUplow.getPatientId())){
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        boolean result = uplowRecordService.saveOrUpdateUplowRecord(sugarValueUplow);
        String logContent = String.format("设置血糖上下限，患者id：%d", sugarValueUplow.getPatientId());
        baseCommonService.addLog(logContent, OPERATE_TYPE_ADD);
        return result ? Result.OK() : error(SystemState.ResponseState.STATE_OPERATION_FAILURE);
    }

    @ApiOperation(value = "血糖记录列表", response = SugarValueLineData.class)
    @PostMapping("/1010107")
    public Result<?> pageSugarRecords(@RequestBody SugarValueRequest request){
        Integer patientId = request.getPatientId();
        Date startTime = request.getStartTime();
        Date endTime = request.getEndTime();
        if (isIntParamInvalid(patientId)
                || startTime == null
                || endTime == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        if (DateUtil.compare(startTime, endTime) > 0) {
            return error(SystemState.ResponseState.STATE_PARAMS_ERROR);
        }
        Integer orderType = request.getOrderType();
        if (orderType == null || orderType != Constant.DESC) {
            orderType = Constant.ASC;
        }
        SugarValueLineData result = sugarRecordService.pageSugarRecords(patientId, startTime, endTime,
                request.getTimeType(), request.getSourceType(), orderType);
        return Result.OK(result);
    }

}
